package com.atguigu.zy.interview.juc.thread;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Jungle
 * @create 2022-09-03 15:25
 * @formatter:off
 * 第四种获得java多线程的方式，线程池,
 *     注意：池字一定要关闭
 *     注意：阿里巴巴开发手册明确规定线程不能显示创建和使用Executors创建，需要手动创建]
 *     CallerRunsPolicy :调用者运行机制，demo中多余的任务会用main线程执行
 *
 *  拒绝策略  AbortPolicy  超过最大线程数+队列深度=上限  直接抛异常
 *      CallerRunsPolicy  调用者线程去执行，如果main线程运行这些程序，用main线程来运行
 *      DiscardOldestPolicy   超过最大线程数+队列深度抛弃等待最久的
 *      DiscardPolicy   超过最大线程数+队列深度  直接抛弃，不会抛异常
 *
 *
 *      最大线程数配置多少：
 *      cpu 密集型配置：逻辑cpu+1
 *      io密集型 ：1、配置2*cpu   2、cpu/1-阻塞系数（0.8-0.9）     16/0.1=160
 * @formatter:on
 */
public class MyThreadPoolDemo {
    public static void main(String[] args) {
        //List<Object> list = new ArrayList<>();
        //Arrays
        //Collections
        //ExecutorService threadPool = Executors.newFixedThreadPool(5);//一池5个线程
        //ExecutorService threadPool = Executors.newSingleThreadExecutor();//一池1个线程
        //ExecutorService threadPool = Executors.newCachedThreadPool();//一池N个线程
        //   模拟10个用户来办理业务，每个用户就是一个外部来的线程
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                5,
                100L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3), //等候区
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());
        try {
            for (int i = 1; i <= 10; i++) {
                int finalI = i;
               threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName()+"\t 号窗口，"+"服务顾客"+ finalI);
                    //@formatter:off  线程暂停 4 秒
                    //try { TimeUnit.SECONDS.sleep( 4 ); } catch (InterruptedException e) { e.printStackTrace();}
                    //@formatter:on
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}
